﻿using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Threading;
using System.Xml;
using System.Windows.Forms;

namespace PublicTransport
{
    class GpsMapImageOsm : GpsMapImage
    {
        private string imageRequest;

        public GpsMapImageOsm(GpsPoint source, GpsPoint destination, int sizeX, int sizeY)
        {
            try
            {
                this.sizeY = sizeY;
                this.sizeX = sizeX;

                xmlRequest = "http://www.yournavigation.org/api/1.0/gosmore.php?format=kml&flat=" + source.Y + "&flon=" + source.X + "&tlat=" + destination.Y + "&tlon=" + destination.X + "&v=foot&fast=1&layer=mapnik";
                XmlDocument xDoc = new XmlDocument();

                WebRequest webRequest = WebRequest.Create(xmlRequest);
                webRequest.Timeout = 10000;
                xDoc.Load(XmlReader.Create(new StringReader((new StreamReader(((HttpWebResponse)(webRequest).GetResponse()).GetResponseStream())).ReadToEnd())));
                webRequest.Abort();

                GpsPoint upperLeft = destination.clone();
                GpsPoint bottomRight = destination.clone();

                imageRequest = "http://pafciu17.dev.openstreetmap.org/?module=map&width=" + sizeX + "&height=" + sizeY + "&transparency=60&thickness=5&points=" + destination.getCoordinatesForOsm() + "&paths=";

                foreach (string s in xDoc.GetElementsByTagName("coordinates")[0].InnerText.Split('\n'))
                {
                    string stringCoordinate = s.Trim();
                    if (stringCoordinate.Length > 9)
                    {
                        try
                        {
                            GpsPoint tmpPoint = new GpsPoint(stringCoordinate);
                            if (upperLeft.X > tmpPoint.X) upperLeft.X = tmpPoint.X;
                            if (upperLeft.Y < tmpPoint.Y) upperLeft.Y = tmpPoint.Y;
                            if (bottomRight.X < tmpPoint.X) bottomRight.X = tmpPoint.X;
                            if (bottomRight.Y > tmpPoint.Y) bottomRight.Y = tmpPoint.Y;
                            imageRequest += tmpPoint.getCoordinatesForOsm() + ",";
                        }
                        catch (Exception ex)
                        {
                        }
                    }
                }
                if (imageRequest[imageRequest.Length - 1].Equals(','))
                {
                    imageRequest = imageRequest.Substring(0, imageRequest.Length - 1);
                }

                zoom = (int)(Math.Log(Math.Min(((double)sizeX) / (bottomRight.X - upperLeft.X), ((double)sizeY) / (upperLeft.Y - bottomRight.Y)) * 1.46025) / Math.Log(2)) - 1;
                centerPoint = upperLeft.getCenterGpsPoint(bottomRight);
                imageRequest += "&center=";
                constructorFinished = true;
                getImage();
            }
            catch (Exception ex)
            {
                error = ex.Message;
                finished = true;
            }
        }

        public override void getImage()
        {
            if (!httpBlock && constructorFinished)
            {
                httpBlock = true;
                finished = false;
                ok = false;
                ThreadStart thread = () =>
                {
                    try
                    {
                        WebRequest webRequest = WebRequest.Create(imageRequest + centerPoint.getCoordinatesForOsm() + "&zoom=" + zoom);
                        webRequest.Timeout = 10000;
                        image = new System.Drawing.Bitmap(((HttpWebResponse)webRequest.GetResponse()).GetResponseStream());
                        webRequest.Abort();
                        httpBlock = false;
                        Point posun = degreesToPixels(centerPoint);
                        upperLeftPixels = new Point((int)Math.Round(posun.X - (double)sizeX / 2.0), (int)Math.Round(posun.Y - (double)sizeY / 2.0));
                        ok = true;
                    }
                    catch (Exception ex)
                    {
                        httpBlock = false;
                        error = ex.Message;
                    }
                    finished = true;
                };
                thread.Invoke();
            }
        }
    }
}
